package mas;

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.TextArea;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JFrame;

/** Class provides a GUI along with acting as a chat room server, giving 
 * functionality such as broadcasting messages to all members of the chat room
 * 
 * Advanced Java Programming - ICA 2 Middleware 
 * @author Carl Morphet, Matt Constable, Stephen Pammenter
 * Teesside University
 * @version %I% 
 * Created: Apr 19, 2012
 */
public class Chat3Server extends JFrame
{	
    /** GUI Components */
    private TextArea msgArea, memberArea;
    
    /** The name of the Chat3Server */
    private String name;
    
    /** UserAgents used within the Chat3Server */
    private UserAgent  manager, chatAgent;
    
    /** A Set of type String which holds all the members identifiers */
    private Set<String> members;
    
    /** Constructor which carries out all major class functionality 
     * 
     * @param portal The portal associated with this Chat3Server
     * @param name The name of the Chat3Server instance
     */
    public Chat3Server(Portal portal, String name)
    {	
        super();
        members = Collections.synchronizedSet( new HashSet<String>() );
        this.name = name;
        
        if (name == null)
        {	
            name = "room1";
            sysout("WARNING: no name supplied, naming as " + name);
        }

        /** Creation and instantiation of a manager agent which handles join 
         * and leave messages */
        manager = new UserAgent(name + " Manager")
        {
            @Override
            public void msgHandler(Message message)
            {
                if(message.getMessage().equals("join"))
                    addMember(message.getSender());
            
                else if(message.getMessage().equals("leave"))
                    removeMember(message.getSender());
                
                manager.msgHandler(message);
                System.out.println("Looping, in class Chat3Server");
            }
        };
        portal.registerAgent(manager.getName(), manager);

        /** Creation and instantiation of a ChatAgent */
        chatAgent = new UserAgent(name)
        {
            @Override
            public void msgHandler(Message message)
            {
                if(members.contains(message.getSender().intern()))
                {
                    msgArea.append("\n" + message.getSender() + "\t" + message.getMessage());
                    broadcast(message);
                }
            }
        };
        portal.registerAgent(chatAgent.getName(), chatAgent);

        /** Setting up the Chat3Servers GUI components */
        setTitle("ChatRoom: " + name);
        msgArea = new TextArea(12, 60);
        memberArea = new TextArea(12, 20);

        Container main = getContentPane();
        main.setLayout(new FlowLayout());
        main.add(memberArea);
        refreshMemberArea();

        main.add(msgArea);
        msgArea.setText("Messages");

        /** Setting the Chat3Servers JFrame size and visibility */
        pack();
        setVisible(true);
    }
    
    /** Method which takes a String and prints it to console with additional 
     * formatting
     * 
     * @param string The string to be printed
     */
    private void sysout(String str)
    {	
        System.out.println("["+name+"] "+ str);
    }

    /** TODO: Make this work properly
     *  Method which takes a Message object and sends it to all chat 
     * members 
     * 
     * @param msg The message to be broadcast
     */
    private void broadcast(Message msg)
    {	
        for(String m : members)
        chatAgent.msgHandler(msg);     
    }

    /** Method which adds a member to the Chat3Servers collection of members 
     * and refreshes the member text area
     * 
     * @param name The identifier of the agent to add
     */
    public void addMember(String name)
    {	
        members.add(name.intern());	
        refreshMemberArea();
    }

    /** Method which removes a member from the Chat3Servers collection of 
     * members and refreshes the member text area
     * 
     * @param name The identifier of the agent to be removed
     */
    public void removeMember(String name)
    {	
        members.remove(name.intern());
        refreshMemberArea();
    }

    /** Method which refreshes the text area which displays all of the active 
     * members of the Chat3Server 
     */
    public void refreshMemberArea()
    {	
        sysout("refreshing members");

        memberArea.setText("Members");

        for(String m : members)
        {	
            sysout("Member = " + m);
            memberArea.append("\n" + m);
        }
    }
}

